package com.wodan.zhongjinjicang.common.orm.command.write;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.Callable;

import com.wodan.zhongjinjicang.common.orm.RdsCommonWriteDao;
import com.wodan.zhongjinjicang.common.orm.command.base.AbstractSqlCommandExecutor;
import com.wodan.zhongjinjicang.common.orm.metadata.MethodMetaData;
import com.wodan.zhongjinjicang.common.orm.metadata.TableFieldMetaData;
import com.wodan.zhongjinjicang.common.orm.metadata.TableMetaData;
import com.wodan.zhongjinjicang.common.orm.utils.ArrayUtils;
import com.wodan.zhongjinjicang.common.orm.utils.ReflectionUtils;
import com.wodan.zhongjinjicang.common.orm.utils.SqlGenernateUtils;
import org.apache.ibatis.mapping.SqlCommandType;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSON;


/**
 * 插入操作的执行者
 * 
 * @ClassName: SqlInsertExecutor
 * @author Administrator
 * @date 2015-11-5 下午4:43:12
 * @history
 * 
 */
public class SqlUpdateByIdExecutor extends AbstractSqlCommandExecutor {
	@Override
	protected Object doExecute(final TableMetaData tableMetaData, MethodMetaData methodMetaData, Object[] args) {
		Assert.notEmpty(args);
		Assert.isTrue(args.length == 1);

		// 取出entity字段
		final Object entity = (Object) args[0];
		
		// 从表中获取id字段
		TableFieldMetaData idField = tableMetaData.getIdField();
		
		// 创建列名和value的map
		Map<String, Object> columnNameMap = super.resolveBeanToColumnNameMap(entity, tableMetaData);
		
		// 取出id字段，并从需要更新数据的map中移除id字段
		Object idColumnValue = columnNameMap.remove(idField.getColumnName().toString());
		if (idColumnValue == null) {
			throw new IllegalArgumentException("实体bean的主键id字段为空：" + JSON.toJSONString(entity));
		}
		
		// 判断bean中是否包含数据
		if(CollectionUtils.isEmpty(columnNameMap)) {
			throw new IllegalArgumentException("实体bean中需要更新的内容为空：" + JSON.toJSONString(entity));
		}

		// 创建sql语句的必须元素
		final String tableName = tableMetaData.getTableName();
		final String[] setColumns = columnNameMap.keySet().toArray(new String[columnNameMap.size()]);
		final String[] conditionColumns = new String[] { idField.getColumnName().toString() };
		final Object[] setAndCoditionValues = ArrayUtils.toArray(Object.class, columnNameMap.values(), idColumnValue);

		// 生成sql语句
		final String sql = super.createCachedSqlScript(new Callable<String>() {
			@Override
			public String call() throws Exception {
				return SqlGenernateUtils.createUpdateSql(tableName, setColumns, conditionColumns);
			}
		}, tableName, setColumns, conditionColumns);

		// 执行sql语句
		return jdbcTemplate.update(sql, setAndCoditionValues);
	}

	@Override
	public Method getProxyMethod() {
		return ReflectionUtils.findMethod(RdsCommonWriteDao.class, "update", Object.class);
	}

	@Override
	protected boolean isEntityMustHaveIdField() {
		return true;
	}
	
	@Override
	public SqlCommandType getSqlCommandType() {
		return SqlCommandType.UPDATE;
	}
}
